﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Yto.Common.Dependency;
using Yto.Common.Linq;
using Yto.Repositories;
using Yto.Unitwork;

namespace com.ytocargo.Core.BackgroundJobInfos
{
    public class BackgroundJobInfoStore : IBackgroundJobInfoStore, ITransient
    {
        private readonly IBaseRepository<BackgroundJobInfo> _rep;

        public IQueryableAsync queryableAsync { get; set; }

        public BackgroundJobInfoStore(IBaseRepository<BackgroundJobInfo> repository)
        {
            _rep = repository;
            queryableAsync = QueryableAsync.Instance;
        }

        public Task DeleteAsync(BackgroundJobInfo jobInfo)
        {
            return _rep.DeleteAsync(jobInfo);
        }

        [Unitwork]
        public virtual Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int MaxCount)
        {
            var list = _rep.GetAll()
                .Where(t => !t.IsAbandoned && t.NextTryTime < DateTime.Now &&!t.IsDelete)
                .OrderBy(t => t.Priority)
                .ThenBy(t => t.TryCount)
                .ThenBy(t => t.NextTryTime)
                .Take(MaxCount)
                .ToList();

            return Task.FromResult(list);
        }

        public void Insert(BackgroundJobInfo jobInfo)
        {
            _rep.Insert(jobInfo);
        }

        public Task InsertAsync(BackgroundJobInfo jobInfo)
        {
            return _rep.InsertAsync(jobInfo);
        }

        public Task<BackgroundJobInfo> UpdateAsync(BackgroundJobInfo jobInfo)
        {
            return _rep.UpdateAsync(jobInfo);
        }

        public IQueryable<BackgroundJobInfo> GetAll()
        {
            return _rep.GetAll();
        }

        public Task<List<BackgroundJobInfo>> GetListByPredicate(Expression<Func<BackgroundJobInfo, bool>> expression)
        {
            return queryableAsync.ToListAsync(_rep.GetAll().Where(expression));
        }

        public Task<int> CountByPredicate(Expression<Func<BackgroundJobInfo, bool>> expression)
        {
            return queryableAsync.CountAsync(_rep.GetAll().Where(expression));
        }
    }
}
